//
// Created by lingzhitech on 25-8-5.
//
#include <gtest/gtest.h>
#include "../material/HandleInput.h"
TEST(ch6, test01) {
    std::cout << "ch6 test01" << std::endl;
}
void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

TEST(ch6, test02exercise0610) {
    int a   = 1, b = 2;
    std::cout << a << " " << b << std::endl;
    swap(&a, &b);
    std::cout << a << " " << b << std::endl;
}

//关于find字符串中字符的位置和出现次数
std::string::size_type find_char(const std::string &s, char c,
                                 std::string::size_type &occurs) {
    auto ret = s.size(); // position of the first occurrence, if any
    occurs = 0; // set the occurrence count parameter
    for (decltype(ret) i = 0; i != s.size(); ++i) {
        if (s[i] == c) {
            if (ret == s.size())
                ret = i; // remember the first occurrence of c
            ++occurs; // increment the occurrence count
        }
    }
    return ret; // count is returned implicitly in occurs
}

void swap(int &a, int &b) {
    auto temp = a;
    a = b;
    b = temp;
}

TEST(ch6, test03exercise0612) {
    int a = 1, b = 2;
    std::cout << a << " " << b << std::endl;
    swap(a, b);
    std::cout << a << " " << b << std::endl;
    int c[2] = {1, 2};
}

void print(const char *cp) {
    if (cp) {
        while (*cp) {
            std::cout << *cp++;
        }
    }
}

TEST(ch6, test04usingamarkertospecifytheextentofanarray) {
    char array[] = "Hello world";
    print(array);
}

void print(const int *beg, const int *end) {
    // print every element starting at beg up to but not including end
    while (beg != end)
        std::cout << *beg++ << std::endl; // print the current element
    // and advance the pointer
}

TEST(ch6, test05arrayparametersusingthestandardlibraryconventions) {
    int j[2] = {0, 1};
    // j is converted to a pointer to the first element in j
    // the second argument is a pointer to one past the end of j
    print(std::begin(j), std::end(j)); // begin and end functions
}

void print(const int ia[], size_t size) {
    for (size_t i = 0; i < size; i++) {
        std::cout << ia[i] << std::endl;
    }
}

TEST(ch6, test06explicitlypassingasizeparameter) {
    int ia[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    print(ia, 10);
}

void print(int (&arr)[10]) {
    for (auto elem: arr) {
        std::cout << elem << std::endl;
    }
}

TEST(ch6, test07arrayreferenceparameter) {
    int k[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    print(k);
}

int larger(int val, const int *ptr) {
    return val > *ptr ? val : *ptr;
}

TEST(ch6, test08exercise0621) {
    int a = 1, b = 2;
    std::cout << larger(a, &b) << std::endl;
}

void swapIntPtr(int **a, int **b) {
    int *temp = *a;
    *a = *b;
    *b = temp;
}

TEST(ch6, test09exercise0622) {
    int *a = new int(5);
    int *b = new int(6);
    std::cout << *a << " " << *b << std::endl;
    swapIntPtr(&a, &b);
    std::cout << *a << " " << *b << std::endl;
}

void error_msg(std::initializer_list<std::string> il) {
    for (auto it = il.begin(); it != il.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;
}

TEST(ch6, test10initializerlist) {
    error_msg({"abc", "def", "ghi", "lmn"});
}

void add_ints(std::initializer_list<int>ints) {
    int sum = 0;
    for (auto i: ints) {
        sum += i;
    }
    std::cout << sum << std::endl;
}
TEST(ch6, test11exercise0627) {
    add_ints({1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
}

char &get_val(std::string &str, std::string::size_type ix) {
    return str[ix];
}

TEST(ch6, test12referencereturnsarelvalues) {
    std::string s = "hello world";
    get_val(s, 0) = 'a';
    std::cout << s << std::endl;
}

TEST(ch6, test13exitsuccessandexitfailure) {
    std::cout << EXIT_SUCCESS << std::endl;//0
    std::cout << EXIT_FAILURE << std::endl;//1
}

//目的是返回数组指针，这个数组的所有元素都是i
auto func(int i) -> int(*)[10] {
    int *a = new int[10];
    for (size_t j = 0; j < 10; ++j) {
        a[j] = i;
    }

    return reinterpret_cast<int(*)[10]>(a);
}
TEST(ch6, test14trailingreturntype) {
    int elem = 8;
    int (*ptr)[10] = func(elem);
    for (size_t i = 0; i < 10; ++i) {
        std::cout << (*ptr)[i] << " ";
    }
}

void printVector(std::vector<int>::iterator first, std::vector<int>::iterator last) {
    if (first == last) {
        return;
    }
    printVector(first, last - 1);
    std::cout << *(last - 1) << " ";

}
TEST(ch6, test15exercise0633) {
    std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    auto first = std::begin(v);
    auto last = std::end(v);
    printVector(first, last);
}

int odd[] = {1,3,5,7,9};
int even[] = {0,2,4,6,8};
// returns a pointer to an array of five int elements
decltype(odd) *arrPtr(int i)
{
    return (i % 2) ? &odd : &even; // returns a pointer to the array
}

TEST(ch6, test16usingdecltype) {
    int (*ret)[5] = arrPtr(5);
    std::cout << (*ret)[0] << std::endl;
}

decltype(odd) &chooseArray(int i)
{
    return (i % 2) ? odd : even; // returns a pointer to the array
}

TEST(ch6, test17exercise0638) {
    int (&ret)[5] = chooseArray(5);
    std::cout << ret[0] << std::endl;
}